package com.burgeon.backend.SHOPBACKEND.service.Impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.burgeon.backend.SHOP.service.SystemService;
import com.burgeon.backend.SHOPBACKEND.entity.ShopKf;
import com.burgeon.backend.SHOPBACKEND.entity.WeiKF;
import com.burgeon.backend.SHOPBACKEND.mappers.WeChatKfMapper;
import com.burgeon.backend.SHOPBACKEND.service.AWechatService;
import com.burgeon.backend.SHOPBACKEND.service.WeChatKFService;

import com.burgeon.backend.SHOPBACKEND.service.ex.DataNotFoundException;
import com.burgeon.backend.SHOPBACKEND.service.ex.DeleteException;
import com.burgeon.backend.SHOPBACKEND.service.ex.UploadException;
import com.burgeon.backend.Util.menu.MyX509TrustManager;
import com.burgeon.backend.Util.menu.WeChatInfo;
import com.burgeon.backend.Util.menu.WeixinUtil;
import com.burgeon.backend.Util.wechatUtil.EmojiUtil;
import com.burgeon.backend.Util.wechatUtil.WeXinHuiFu;
import com.burgeon.backend.WeChat.Wxacode;
import com.burgeon.backend.entity.Info;
import com.burgeon.backend.mappers.AccountMapper;


import com.burgeon.backend.service.WechatService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.*;

import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

@Service
public class WeChatKFServiceImpl implements WeChatKFService {
    private final static Log log = LogFactory.getLog(WeChatKFService.class);
    @Autowired
    private AccountMapper accountMapper;
    @Autowired
    private SystemService systemService;
    @Autowired
    private WechatService wechatService;
    @Autowired
    private WeChatKfMapper weChatKfMapper;
    @Autowired
    private Wxacode wxacode;
    // 获取ticket
    private static final String GET_QRCODE_URL = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={TOKEN}";
    // 换取二维码
    private static final String QR_CODE_URL = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket={TICKET}";


    /**
     * 获取微信所有客服列表
     * @return
     */
    public ArrayList<WeiKF> findWeKFAll(String token){
       // Info info = GetInfo(token);
        String accessToken = systemService.GetAccesToken(token);

        // https://api.weixin.qq.com/cgi-bin/customservice/getkflist?access_token=ACCESS_TOKEN
        String action = "https://api.weixin.qq.com/cgi-bin/customservice/getkflist?access_token="+accessToken;
        //发送给微信
        JSONObject jsonObject = WeixinUtil.httpRequest(action,"GET","");
        System.err.println(jsonObject);
        JSONArray jsonArray = jsonObject.getJSONArray("kf_list");
        ArrayList<WeiKF> weiKFS = new ArrayList<>();
        for (int i=0;i<jsonArray.size();i++){
            WeiKF weiKF = new WeiKF();
            weiKF.setKfAccount(jsonArray.getJSONObject(i).getString("kf_account"));
            weiKF.setKfNick(jsonArray.getJSONObject(i).getString("kf_nick"));
            weiKF.setKfWx(jsonArray.getJSONObject(i).getString("kf_wx"));
            weiKF.setKfId(jsonArray.getJSONObject(i).getString("kf_id"));
            weiKF.setKfHeadimgurl(jsonArray.getJSONObject(i).getString("kf_headimgurl"));
            // System.err.println(weiKF);
            weiKFS.add(weiKF);
        }
        log.info(weiKFS);
        return weiKFS;
    }

    /**
     * 添加客服账号
     * @param token
     * @param kfAccount
     * @param nickName
     * @param password
     */
    public void addKF(String token,String kfAccount,String nickName,String password){
        String accessToken = systemService.GetAccesToken(token);
        //POST https://api.weixin.qq.com/customservice/kfaccount/add?access_token=ACCESS_TOKEN
        String action = "https://api.weixin.qq.com/customservice/kfaccount/add?access_token="+accessToken;
        String json = "{\"kf_account\": \""+kfAccount+"\",\"nickname\": \""+nickName +"\"}";
        JSONObject jsonObject = WeixinUtil.httpRequest(action,"POST",json);
        System.err.println(jsonObject);
    }

    /**
     * 绑定客服账号
     * @param token
     * @param kfAccount
     * @param kfWx
     */
    //https://api.weixin.qq.com/customservice/kfaccount/inviteworker?
    public void bindKF(String token,String kfAccount,String kfWx){
        String accessToken = systemService.GetAccesToken(token);
        String action = "https://api.weixin.qq.com/customservice/kfaccount/inviteworker?access_token="+accessToken;
        String json = "{\"kf_account\": \""+kfAccount+"\",\"invite_wx\": \""+kfWx +"\"}";
        JSONObject jsonObject = WeixinUtil.httpRequest(action,"POST",json);
        System.err.println(jsonObject);
    }

    /**
     * 设置客服信息
     * @param token
     * @param kfAccount
     * @param nickName
     */
    public void updateKF(String token,String kfAccount,String nickName){
        String accessToken = systemService.GetAccesToken(token);
        //String accessToken = wechatService.GetAccesToken(token);
        String action = "https://api.weixin.qq.com/customservice/kfaccount/update?access_token="+accessToken;
        String json = "{\"kf_account\": \""+kfAccount+"\",\"nickname\": \""+nickName +"\"}";
        JSONObject jsonObject = WeixinUtil.httpRequest(action,"POST",json);
        System.err.println(jsonObject);
    }

    /**
     * 删除客服
     * @param token
     * @param kfAccount
     */
    public void DelKF(String token,String kfAccount){
        String accessToken = systemService.GetAccesToken(token);
        //String accessToken = wechatService.GetAccesToken(token);
        String action = "https://api.weixin.qq.com/customservice/kfaccount/del?access_token="+accessToken;
        String json = "{\"kf_account\": \""+kfAccount+"\"}";
        JSONObject jsonObject = WeixinUtil.httpRequest(action,"POST",json);
        System.err.println(jsonObject);
    }

    public String addCustomer(MultipartFile file, String kfAccount,String token) {
        String accessToken = systemService.GetAccesToken(token);
        //添加头像信息
        String headUrl = "https://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?access_token=" + accessToken + "&kf_account=" + kfAccount;
        String result = null;
        StringBuilder buffer = new StringBuilder();
        BufferedReader reader = null;
        try {
            // 创建SSLContext对象，并使用我们指定的信任管理器初始化
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();
            //头像连接
            URL urlObj = new URL(headUrl);
            HttpsURLConnection con = (HttpsURLConnection) urlObj.openConnection();
            con.setSSLSocketFactory(ssf);
            // 以POST方式提交表单，默认get方式
            con.setRequestMethod("POST");
            con.setDoInput(true);
            con.setDoOutput(true);
            // POST方式不能使用缓存
            con.setUseCaches(false);
            // 设置请求头信息
            con.setRequestProperty("Connection", "Keep-Alive");
            con.setRequestProperty("Charset", "UTF-8");
            // 设置边界
            String boundary = "----------" + System.currentTimeMillis();
            con.setRequestProperty("Content-Type", "multipart/form-data; boundary="
                    + boundary);

            // 第一部分
            StringBuilder sb = new StringBuilder();
            // 必须多两道线
            sb.append("--");
            sb.append(boundary);
            sb.append("\r\n");
            //上传头像和上传多媒体主要是下面这句话有却别
            //头像：获取文件名称
            String fileNme = System.currentTimeMillis() + file.getOriginalFilename();//.substring(file.getOriginalFilename().lastIndexOf("."));

            log.info("a.添加客服 ------原始文件名------fileNme---" + fileNme);
            sb.append("Content-Disposition: form-data;name=\"media\";filename=\"").append(fileNme).append("\"\r\n");
            //获取文件类型设置成请求头
            sb.append("Content-Type:").append(file.getContentType()).append("\r\n\r\n");
            byte[] head = sb.toString().getBytes("utf-8");
            // 获得输出流
            OutputStream out = new DataOutputStream(con.getOutputStream());
            // 输出表头
            out.write(head);

            log.info("a.添加客服 ------输出表头------sb---" + sb.toString());
            // 文件正文部分
            // 把文件以流文件的方式推入到url中
            InputStream in = file.getInputStream();
            int bytes = 0;
            byte[] bufferOut = new byte[1024];
            while ((bytes = in.read(bufferOut)) != -1) {
                out.write(bufferOut, 0, bytes);
            }
            in.close();
            // 结尾部分// 定义最后数据分隔线
            byte[] foot = ("\r\n--" + boundary + "--\r\n").getBytes("utf-8");
            out.write(foot);
            out.flush();
            out.close();
            // 定义BufferedReader输出流来读取URL的响应
            reader = new BufferedReader(new InputStreamReader(
                    con.getInputStream()));
            String line = null;
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            result = buffer.toString();
        } catch (IOException e) {
            log.error("============添加头像接口异常==========="+e.getMessage());
        } catch (NoSuchAlgorithmException | KeyManagementException | NoSuchProviderException e) {
            e.printStackTrace();
            log.error("============添加头像接口关闭reader异常==========="+e.getMessage());
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    log.error("============添加头像接口关闭reader异常==========="+e.getMessage());
                }
            }
        }
        log.info("------上传微信客服完成返回的数据-------" + result);
        return result;
    }

    //生成小程序码
    @Override
    public String creatWeCodeUrl(String token) {
        String linkImg = weChatKfMapper.getCodeUrl(token);
        System.err.println(linkImg);
        if(null == linkImg){
            System.err.println("尽快");
            String accessToken = systemService.GetAccesToken(token);
            System.err.println(accessToken);
            linkImg = wxacode.createKfcode(accessToken,token);

            weChatKfMapper.insertCodeUrl(token,linkImg);
        }

        return linkImg;
    }

    /**
     * s扫码绑定获取通知客服
     * @param openid
     * @param token
     * @return
     */
    @Override
    public Integer insertOpenId(String openid, String token) {
        ShopKf shopKf1 = weChatKfMapper.getKfByOpenid(token,openid);
        System.err.println(shopKf1);
        if(null != shopKf1){
            throw new DataNotFoundException("您已是客服！");
        }
        String accessToken = wechatService.GetAccesToken(token);
        System.err.println(accessToken);
        JSONObject jsonObject = getUserInfo(accessToken,openid,token);
        ShopKf shopKf = new ShopKf();
        Integer row=null;
        if (null != jsonObject) {
            System.err.println(jsonObject.containsKey("errcode"));
            if (!jsonObject.containsKey("errcode")) {

                // 用户的标识
                shopKf.setOpenid(jsonObject.getString("openid"));
                shopKf.setSubscribe(jsonObject.getString("subscribe"));
                if ("0".equals(shopKf.getSubscribe())) {
                    log.info("用户并没有关注本公众号" + jsonObject);
                    throw new DataNotFoundException("您没有关注公众号");
                }

                // 昵称
                shopKf.setKfNick(jsonObject.getString("nickname"));

                // 用户的性别（1是男性，2是女性，0是未知）
                if ("1".equals(jsonObject.getString("sex"))) {
                    shopKf.setKfSex("男");
                } else if ("2".equals(jsonObject.getString("sex"))) {
                    shopKf.setKfSex("女");
                } else {
                    shopKf.setKfSex("未知");
                }
                // 用户头像
                shopKf.setKfHeadimgurl(jsonObject.getString("headimgurl"));
                shopKf.setToken(token);
                row = weChatKfMapper.bindKf(shopKf);


            }else{
                log.info("错误信息errcode："+jsonObject.getString("errcode"));
                throw new DataNotFoundException("绑定错误"+jsonObject.getString("errcode"));
            }
        }
       // shopKf.setToken(token);

        return row;
    }

    //商品列表
    @Override
    public ArrayList<ShopKf> findWeKF(String token) throws UnsupportedEncodingException {
        ArrayList<ShopKf> shopKfs = weChatKfMapper.getKf(token);
//        ArrayList<ShopKf> shopKfs1 = new ArrayList<>();
//        for (ShopKf shopKf:shopKfs) {
//            String nickname = new String(Base64.decodeBase64(shopKf.getKfNick()),"UTF-8");
//            shopKf.setKfNick(nickname);
//            shopKfs1.add(shopKf);
//        }
        return shopKfs;
    }



    /**
     * 获取微信用户的信息
     * @param accessToken
     * @param openId
     * @return
     */
//    @Override
    private JSONObject getUserInfo(String accessToken, String openId,String token) throws DataNotFoundException{

        // 上传文件请求路径
        String action = "https://api.weixin.qq.com/cgi-bin/user/info?access_token="
                + accessToken+"&openid="+openId;
        System.err.println("j呼吸道咖啡机"+openId);
        // 拼接获取用户信息接口的请求地址
//        String requestUrl = ProjectConst.GET_WEIXIN_USER_URL.replace("ACCESS_TOKEN", accessToken).replace(
//                "OPENID", openId);
        // 获取用户信息(返回的是Json格式内容)
        //封装获取到的用户信息

        try {
            URL urlGet = new URL(action);
            HttpsURLConnection http = (HttpsURLConnection) urlGet.openConnection();
            http.setRequestMethod("GET"); // 必须是get方式请求
            http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            http.setDoOutput(true);
            http.setDoInput(true);
            System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒
            System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒
            http.connect();
            InputStream is = http.getInputStream();
            int size = is.available();
            byte[] jsonBytes = new byte[size];
            is.read(jsonBytes);
            String result = new String(jsonBytes, "UTF-8");
            System.err.println("结果"+result);
            JSONObject jsonObject = JSONArray.parseObject(result);
            //System.err.println(jsonObject);

                    //OPENID2
                  //  weixinUserInfo.setHeadImgUrl(jsonObject.getString("OPENID2"));
//                    System.err.println(weixinUserInfo);
//                    long endTime = System.currentTimeMillis();    //获取结束时间
//                    System.out.println("程序运行时间：" + (endTime - startTime) + "ms");    //输出程序运行时间

//                } catch (Exception e) {
//
//                        String errorCode = jsonObject.getString("errcode");
//                        String errorMsg = jsonObject.getString("errmsg");
//                        log.info("由于"+errorCode +"错误码；错误信息为："+errorMsg+"；导致获取用户信息失败");
//                        log.error(e.getMessage());
//
//                    e.printStackTrace();
//                    throw new DataNotFoundException(e.getMessage());
//
          return jsonObject;
        } catch (Exception e) {
            e.printStackTrace();
            log.info("失败");
            return null;

        }

    }

    /**
     * 删除客服根据id
     * @param token
     * @param id
     * @return
     */
    @Override
    public Integer deleteKfById(String token, String id) {
        if (null == token || token.isEmpty()) {
            System.out.println("t");
            throw new UploadException("没有选择token");
        }else if(null == id || id.isEmpty()){
            throw new UploadException("请选择要删除的客服");
        }
        Integer data = weChatKfMapper.deleteKfById(token,id);
        if(data==0){
            throw new DeleteException("删除失败");
        }
        return data;
    }

    private String getYJQrCode(String kfAccount,String token){
        String returnUrl = null;

        String accessToken = wechatService.GetAccesToken(token);

        //String req = "{\"expire_seconds\": 604800, \"action_name\": \"QR_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": "+daoId+" }}}";
        String req = "{\"action_name\": \"QR_LIMIT_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": "+kfAccount+" }}}";
        String url = GET_QRCODE_URL.replace("{TOKEN}", accessToken);

        JSONObject res =WeixinUtil.httpRequest(url,"GET",req);
        //System.err.println("二维码"+res);

        // System.out.println("获取二维码出参" + res);
        String ticket = res.getString("ticket");
        returnUrl = QR_CODE_URL.replace("{TICKET}", ticket);
        System.err.println(returnUrl);

        //b.将临时带参二维码存入数据库
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, 30);
        Date date = cal.getTime();

        return returnUrl;
    }


    private Info GetInfo(String token) {
        return accountMapper.GetAccData(token);
    }

}
